package com.fdq.dianping.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.fdq.dianping.config.GetHttpSessionConfig;
import com.fdq.dianping.entity.Message;
import com.fdq.dianping.entity.dto.UserDto;
import com.fdq.dianping.util.JwtUtil;
import com.fdq.dianping.util.MessageUtils;
import com.fdq.dianping.util.ThreadLocalUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import jakarta.websocket.*;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@ServerEndpoint(value = "/chat/{token}",configurator = GetHttpSessionConfig.class)
@Component
public class ChatController {

    //存放可以互相发送信息的用户，键为userId,值为该用户的session
    private static final Map<Integer, Session> onlineUsers = new ConcurrentHashMap<>();

    // 未读消息存储，键为用户ID，值为消息列表
    private static final Map<Integer, List<String>> unreadMessages = new ConcurrentHashMap<>();

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    private Integer userId;

    /**
     * 建立websocket连接后，被调用
     * @param session
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("token") String token){
        //获取当前登录用户信息
        //从jwt中解析出的数据
        Map<String, Object> claim = null;
        claim = JwtUtil.parseToken(token);
        this.userId = (Integer) claim.get("id");
        try {
            //将用户的webSocket session保存
            if (userId != null) {
                onlineUsers.put(userId,session);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        // 检查是否有未读消息
        if (userId != null){
            List<String> messages = unreadMessages.getOrDefault(userId, new ArrayList<>());
            if (!messages.isEmpty()) {
                for (String message : messages) {
                    try {
                        session.getBasicRemote().sendText(message);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                unreadMessages.put(userId, new ArrayList<>()); // 清空未读消息
            }
        }else {
            System.out.println("noUserOpen!");
        }

        System.out.println("welcome:");
    }



    /**
     * 浏览器发送消息到服务端，该方法被调用
     * @param message
     */
    @OnMessage
    public void onMessage(String message) throws IOException {
        System.out.println(message);
        //解析用户发来的信息
        Message msgFromUser = JSONUtil.toBean(message, Message.class);
        //获取消息接收方用户对象的session对象
        Session toSession = onlineUsers.get(msgFromUser.getToUser());

        if (toSession != null && toSession.isOpen()) {
            try {
                //将信息发送给接收的用户
                String msgToUser = MessageUtils.genMessage(false,userId, msgFromUser);
                toSession.getBasicRemote().sendText(msgToUser);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }else {
            // 接收方不在线，保存消息
            String msgToUser = MessageUtils.genMessage(false,userId, msgFromUser);
            List<String> messages = unreadMessages.getOrDefault(msgFromUser.getToUser(), new ArrayList<>());
            messages.add(msgToUser);
            unreadMessages.put(msgFromUser.getToUser(),messages);
        }


    }


    /**
     * 断开 websocket 连接时被调用
     * @param session
     */
    @OnClose
    public void onClose(Session session){
        //从onlineUsers中剔除当前用户的session对象
        if(userId != null){
            onlineUsers.remove(userId);
        }else {
            System.out.println("noUser!");
        }

    }

}
